package com.atguigu.tingshu.live.api;

import com.alibaba.fastjson.JSON;
import com.atguigu.tingshu.common.constant.RedisConstant;
import com.atguigu.tingshu.live.config.LiveRoomContainer;
import com.atguigu.tingshu.model.live.FromUser;
import com.atguigu.tingshu.model.live.SocketMsg;
import com.atguigu.tingshu.vo.user.UserInfoVo;
import jakarta.websocket.*;
import jakarta.websocket.server.PathParam;
import jakarta.websocket.server.ServerEndpoint;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.PathVariable;

import java.text.SimpleDateFormat;
import java.util.Date;

@Controller
@ServerEndpoint("/api/websocket/{roomId}/{token}")//是多例的
public class WebSocketApiController {

    //    @Autowired
    private static RedisTemplate redisTemplate;

//    @Autowired
//    public WebSocketApiController(RedisTemplate redisTemplate) {
//        this.redisTemplate = redisTemplate;
//    }

    @Autowired
    public void setRedisTemplate(RedisTemplate redisTemplate) {
        this.redisTemplate = redisTemplate;
    }


    /**
     * 加入直播间
     * @param roomId
     * @param token
     * @param session
     */
    @OnOpen
    public void OnOpen(@PathParam("roomId") Long roomId, @PathParam("token") String token, Session session){
        System.out.println("加入直播间");
        //根据token获取用户信息
      UserInfoVo userInfoVo = (UserInfoVo)this.redisTemplate.opsForValue().get(RedisConstant.USER_LOGIN_KEY_PREFIX + token);

       //初始化一个消息对象
        SocketMsg msg = new SocketMsg();
        msg.setLiveRoomId(roomId);
        msg.setMsgType(SocketMsg.MsgTypeEnum.JOIN_CHAT.getCode());
        msg.setMsgContent(userInfoVo.getNickname()+ "加入了直播间");
        //发送者
        FromUser fromUser = new FromUser();
        BeanUtils.copyProperties(userInfoVo,fromUser);
        fromUser.setUserId(userInfoVo.getId());
        msg.setFromUser(fromUser);
        msg.setTime(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date()));
        //把当前用户加入到直播间
        LiveRoomContainer.join(roomId,userInfoVo.getId(),session);
        //把消息转发给直播间的每一个用户
       // LiveRoomContainer.sendMsg(msg);
        //发布消息给中间件
        redisTemplate.convertAndSend(RedisConstant.LIVE_MESSAGE_CHANNEL,msg);
    }

    /**
     * 在直播间发送消息进行聊天
     * @param msg
     */
    @OnMessage
    public void OnMessage(String msg){
        System.out.println("获取了消息的内容:" +msg);

       // LiveRoomContainer.sendMsg(JSON.parseObject(msg,SocketMsg.class));
        redisTemplate.convertAndSend(RedisConstant.LIVE_MESSAGE_CHANNEL,JSON.parseObject(msg,SocketMsg.class));
    }

    /**
     * 退出直播间
     * @param roomId
     * @param token
     */
    @OnClose
    public void onClose(@PathParam("roomId") Long roomId, @PathParam("token") String token){
        System.out.println("离开了直播间! ");
        UserInfoVo userInfoVo = (UserInfoVo) this.redisTemplate.opsForValue().get(RedisConstant.USER_LOGIN_KEY_PREFIX + token);
        //从中介者中移除该用户
        LiveRoomContainer.leave(roomId,userInfoVo.getId());
        //发送消息XXX离开了直播间
        SocketMsg msg = new SocketMsg();
        msg.setLiveRoomId(roomId);
        msg.setMsgType(SocketMsg.MsgTypeEnum.CLOSE_SOCKET.getCode());
        msg.setMsgContent(userInfoVo.getNickname() +"离开了直播间 ");
        //发送者
        FromUser fromUser = new FromUser();
        BeanUtils.copyProperties(userInfoVo,fromUser);
        fromUser.setUserId(userInfoVo.getId());
        msg.setTime(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date()));
        //LiveRoomCOntainer.sendMSg(msg);
        redisTemplate.convertAndSend(RedisConstant.LIVE_MESSAGE_CHANNEL,msg);

    }

    /**
     * 连接直播间出错
     * @param roomId
     * @param token
     * @param ex
     */
    @OnError
    public void onError(@PathParam("roomId") Long roomId, @PathParam("token") String token,Throwable ex){
        System.out.println("连接出错! 错误信息: "+ex.getMessage());

        UserInfoVo userInfoVo= (UserInfoVo)this.redisTemplate.opsForValue().get(RedisConstant.USER_LOGIN_KEY_PREFIX +token);
        //从中介者中移除该用户
        LiveRoomContainer.leave(roomId,userInfoVo.getId());
        //发送消息提示XXX离开了直播间
        SocketMsg msg = new SocketMsg();
        msg.setLiveRoomId(roomId);
        msg.setMsgType(SocketMsg.MsgTypeEnum.CLOSE_SOCKET.getCode());
        msg.setMsgContent(userInfoVo.getNickname() + "离开了直播间");
        //发送者
        FromUser fromUser = new FromUser();
        BeanUtils.copyProperties(userInfoVo,fromUser);
        fromUser.setUserId(userInfoVo.getId());
        msg.setFromUser(fromUser);
        msg.setTime(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date()));
        //LiveRoomContainer.sendMsg(msg)
        redisTemplate.convertAndSend(RedisConstant.LIVE_MESSAGE_CHANNEL,msg);

        ex.printStackTrace();
    }
}
